import Phaser from "phaser";

interface customParamType {
  zoomRatio: number;
  gameWidth: number;
  gameHeight: number;
}
/*
  1.8x8 的游戏网格
  2.5种不同颜色的方块
  3.点击选择两个方块
  4.连线规则：直线连接，折角连接（若无直线，玩家最多两个折角才可以连接），所有连接线都不能穿过其他图案
  5.消除机制：完成连线规则的两个方块会在棋盘上消除，当棋盘上所有方块被消除时，玩家胜利，否则游戏失败
  6.消除动画效果
  7.分数系统
*/

export class MatchScene extends Phaser.Scene {
  private gridSize = 8; // 网格大小
  private tileSize = 64; // 每个方块的大小
  private tiles: (Phaser.GameObjects.Image | null)[][] = []; // 存储所有方块
  private selectedTile: Phaser.GameObjects.Image | null = null; // 当前选中的方块
  private colors: string[] = ['red', 'blue', 'green', 'yellow', 'purple']; // 方块颜色
  private score: number = 0; // 分数
  private scoreText: Phaser.GameObjects.Text | null = null; // 分数文本
  public zoomRatio: number;
  public gameWidth: number;
  public gameHeight: number;
  private lineGraphics: Phaser.GameObjects.Graphics | null = null;
  private pointCircles: Phaser.GameObjects.Circle[] = [];

  constructor(config: Phaser.Types.Scenes.SettingsConfig, customParam: customParamType) {
    super(config);
    this.zoomRatio = customParam.zoomRatio;
    this.gameWidth = customParam.gameWidth;
    this.gameHeight = customParam.gameHeight;
  }

  preload(): void {
    // 加载方块图片
    this.colors.forEach(color => {
      this.load.image(color, `/image/${color}.png`);
    });
    this.load.image('particle_texture', `/image/particle.png`);

    this.lineGraphics = this.add.graphics();// 初始化 lineGraphics
    this.lineGraphics.setDepth(1);

    // 添加加载进度事件
    this.load.on('progress', (value: number) => {
      console.log('Loading progress:', value);
    });

    this.load.on('complete', () => {
      console.log('Loading complete');
    });

    this.load.on('loaderror', (file: any) => {
      console.error('Error loading file:', file);
    });
  }

  create(): void {
    console.log('Scene created, dimensions:', this.gameWidth, this.gameHeight);

    // 创建分数显示
    this.createScoreDisplay();

    // 创建网格
    this.createGrid();

    // phaser添加交互点击事件input.on(event, callback, context)，键盘input.keyboard.createCursorKeys()
    this.input.on('gameobjectdown', this.handleTileClick, this);
    // this.input.on('pointerdown', (pointer) => {
    //   console.log('Mouse clicked at:', pointer.x, pointer.y);
    // });

    // 添加调试信息
    console.log('Grid created with tiles:', this.tiles);
  }

  // 创建分数显示
  private createScoreDisplay(): void {
    this.scoreText = this.add.text(16, 16, 'Score: 0', {
      fontSize: '32px',
      color: '#ffffff'
    });
  }

  // 更新分数
  private updateScore(points: number): void {
    this.score += points;
    if (this.scoreText) {
      this.scoreText.setText(`Score: ${this.score}`);
    }
  }

  private createGrid(): void {
    // 计算网格的起始位置，使其居中于游戏窗口中
    const startX = (this.gameWidth - this.gridSize * this.tileSize) / 2;
    const startY = (this.gameHeight - this.gridSize * this.tileSize) / 2;

    console.log('Creating grid at:', startX, startY);

    for (let row = 0; row < this.gridSize; row++) {
      this.tiles[row] = [];
      for (let col = 0; col < this.gridSize; col++) {
        // 随机选择一个颜色
        const color = this.colors[Math.floor(Math.random() * this.colors.length)];
        // 根据网格的起始位置和瓷砖的尺寸计算瓷砖的位置
        const x = startX + col * this.tileSize;
        const y = startY + row * this.tileSize;

        try {
          // 创建砖块（x，y，texture,frame），这里使用Phaser 3 中，Image 是一个非常常用的游戏对象，用于显示静态图像(不能播放动画或使用帧)。它继承自 Phaser.GameObjects.Image 类
          const tile = this.add.image(x, y, color);// 图像资源的键名，必须先通过 this.load.image() 加载。
          tile.setDisplaySize(this.tileSize, this.tileSize);// 设置图像的显示宽度和高度，不会改变原始图像的比例。
          tile.setInteractive();// 使图像对象可以响应鼠标或触摸事件。
          tile.setData('row', row);// setData图像对象附加任意数据，通过getData获取数据值
          tile.setData('col', col);

          this.tiles[row][col] = tile;
        } catch (error) {
          console.error('Error creating tile:', error);
          this.tiles[row][col] = null;
        }
      }
    }
  }

  private handleTileClick(pointer: Phaser.Input.Pointer, gameObject: Phaser.GameObjects.Image): void {
    if (!this.selectedTile) {
      // 第一次选择
      this.selectedTile = gameObject;
      gameObject.setTint(0x00ff00);// 添加色调
    } else {
      // 第二次选择
      // const firstRow = this.selectedTile.getData('row');
      // const firstCol = this.selectedTile.getData('col');
      // const secondRow = gameObject.getData('row');
      // const secondCol = gameObject.getData('col');

      // 检查是否相邻
      // if (this.isAdjacent(firstRow, firstCol, secondRow, secondCol)) {
      //   // 交换方块
      //   this.swapTiles(firstRow, firstCol, secondRow, secondCol);
      // }

      // 检查是否有可消除的组合
      this.checkMatches2(this.selectedTile, gameObject);

      // 清除选中状态
      this.selectedTile.clearTint(); //清除色调
      this.selectedTile = null;
    }
  }

  private isAdjacent(row1: number, col1: number, row2: number, col2: number): boolean {
    // 同行相邻或者同列相邻
    return (Math.abs(row1 - row2) === 1 && col1 === col2) ||
      (Math.abs(col1 - col2) === 1 && row1 === row2);
  }

  private swapTiles(row1: number, col1: number, row2: number, col2: number): void {
    const tile1 = this.tiles[row1][col1];
    const tile2 = this.tiles[row2][col2];

    if (!tile1 || !tile2) return;

    // 交换位置
    const tempX = tile1.x;
    const tempY = tile1.y;
    this.tweens.add({
      targets: tile1,
      x: tile2.x,
      y: tile2.y,
      duration: 200,
      ease: 'Power2'
    });
    this.tweens.add({
      targets: tile2,
      x: tempX,
      y: tempY,
      duration: 200,
      ease: 'Power2'
    });

    // 更新数组
    this.tiles[row1][col1] = tile2;
    this.tiles[row2][col2] = tile1;

    // 更新数据
    tile1.setData('row', row2);
    tile1.setData('col', col2);
    tile2.setData('row', row1);
    tile2.setData('col', col1);

    // 检查是否有可消除的组合
    this.checkMatches();
  }

  private checkMatches(): void {
    let hasMatches = false;

    // 检查水平匹配
    for (let row = 0; row < this.gridSize; row++) {
      for (let col = 0; col < this.gridSize - 2; col++) {
        const tile1 = this.tiles[row][col];
        const tile2 = this.tiles[row][col + 1];
        const tile3 = this.tiles[row][col + 2];

        // 检查水平方向是否有连续三个相同颜色的方块，相同就清除
        if (tile1 && tile2 && tile3 && tile1.texture.key === tile2.texture.key &&
          tile2.texture.key === tile3.texture.key) {
          this.removeTiles([tile1, tile2, tile3]);
          hasMatches = true;
        }
      }
    }

    // 检查垂直匹配
    for (let row = 0; row < this.gridSize - 2; row++) {
      for (let col = 0; col < this.gridSize; col++) {
        const tile1 = this.tiles[row][col];
        const tile2 = this.tiles[row + 1][col];
        const tile3 = this.tiles[row + 2][col];

        // 检查垂直方向是否有连续三个相同颜色的方块，相同就清除
        if (tile1 && tile2 && tile3 && tile1.texture.key === tile2.texture.key &&
          tile2.texture.key === tile3.texture.key) {
          this.removeTiles([tile1, tile2, tile3]);
          hasMatches = true;
        }
      }
    }

    if (hasMatches) {
      // 延迟执行下落动画，等待消除动画完成
      this.time.delayedCall(300, () => {
        this.handleFallingTiles();
      });
    }
  }

  // 检查方块连线情况
  private async checkMatches2(first: Phaser.GameObjects.Image, second: Phaser.GameObjects.Image): void {
    let hasMatches = false;
    const firstRow = first.getData('row');
    const firstCol = first.getData('col');
    const secondRow = second.getData('row');
    const secondCol = second.getData('col');
    if (first && first.texture.key === second.texture.key) {
      let ways: any = []
      if (this.isConnectWithOneTurn(firstRow, firstCol, secondRow, secondCol)) {
        ways = this.isConnectWithOneTurn(firstRow, firstCol, secondRow, secondCol)
      } else if (this.isConnectWithTwoTurns(firstRow, firstCol, secondRow, secondCol)) {
        ways = this.isConnectWithTwoTurns(firstRow, firstCol, secondRow, secondCol)
      }
      if (this.isConnectStraight(firstRow, firstCol, secondRow, secondCol) || ways) {
        await this.drawLinesWithGlow(first, second, ways)
        this.removeTiles([first, second]);
        hasMatches = true;
      }
    }
  }

  private removeTiles(tiles: Phaser.GameObjects.Image[]): void {
    tiles.forEach(tile => {
      // const row = tile.getData('row');
      // const col = tile.getData('col');
      // 添加消除动画
      // this.tweens.add({
      //   targets: tile,
      //   scale: 0,
      //   duration: 200,
      //   ease: 'Power2',
      //   onComplete: () => {
      //     tile.destroy();
      //     this.tiles[row][col] = null;
      //   }
      // });
      this.createExplosionEffect(tile)
    });

    // 更新分数没消除一个方块获取10分
    this.updateScore(tiles.length * 10);
  }

  private handleFallingTiles(): void {
    const startX = (this.gameWidth - this.gridSize * this.tileSize) / 2;
    const startY = (this.gameHeight - this.gridSize * this.tileSize) / 2;

    // 从底部开始检查每一列
    for (let col = 0; col < this.gridSize; col++) {
      let emptyRow = -1;

      // 找到第一个空位
      for (let row = 0; row < this.gridSize; row++) {
        if (!this.tiles[row][col]) {
          emptyRow = row;
          break;
        }
      }

      if (emptyRow !== -1) {
        // 从空位上方开始，将所有方块下移
        for (let row = emptyRow; row > 0; row--) {
          const tile = this.tiles[row - 1][col]; //同列上一行方块
          if (tile) {
            // 更新数组
            this.tiles[row][col] = tile;
            this.tiles[row - 1][col] = null;

            // 更新数据
            tile.setData('row', row);// 每次更新方块位置都要更新数据

            // 添加下落动画
            this.tweens.add({
              targets: tile,
              y: startY + row * this.tileSize,
              duration: 300,
              ease: 'Bounce.easeOut'
            });
          }
        }

        // // 在顶部生成新方块
        // const newColor = this.colors[Math.floor(Math.random() * this.colors.length)];
        // const newTile = this.add.image(startX + col * this.tileSize, startY - this.tileSize, newColor);
        // newTile.setDisplaySize(this.tileSize, this.tileSize);
        // newTile.setInteractive();
        // newTile.setData('row', 0);
        // newTile.setData('col', col);

        // this.tiles[0][col] = newTile;

        // // 添加新方块的下落动画
        // this.tweens.add({
        //   targets: newTile,
        //   y: startY,
        //   duration: 300,
        //   ease: 'Bounce.easeOut'//弹跳效果（Bounce.easeOut）
        // });
      }
    }

    // 延迟检查新的匹配
    this.time.delayedCall(400, () => {
      this.checkMatches();
    });
  }

  private isConnectStraight(row1: number, col1: number, row2: number, col2: number): boolean {
    if (row1 === row2) {
      // 同一行
      const minCol = Math.min(col1, col2);
      const maxCol = Math.max(col1, col2);
      for (let col = minCol + 1; col < maxCol; col++) {
        if (this.tiles[row1][col]) {
          return false;
        }
      }
      return true;
    } else if (col1 === col2) {
      // 同一列
      const minRow = Math.min(row1, row2);
      const maxRow = Math.max(row1, row2);
      for (let row = minRow + 1; row < maxRow; row++) {
        if (this.tiles[row][col1]) {
          return false;
        }
      }
      return true;
    }
    return false;
  }

  // 检查是否可以单折角连接
  private isConnectWithOneTurn(row1: number, col1: number, row2: number, col2: number): any {
    const tile1 = { row: row1, col: col1 }
    const tile2 = { row: row2, col: col2 }
    // 尝试找到折点
    for (let row = 0; row < this.gridSize; row++) {
      if (this.tiles[row][col1] === null && this.tiles[row][col2] === null) {
        // 检查当前行的 col1 和 col2 位置是否都没有方块
        const midTile1 = { row, col: col1 };
        const midTile2 = { row, col: col2 };
        if (this.isConnectStraight(tile1.row, tile1.col, midTile1.row, midTile1.col) && this.isConnectStraight(midTile2.row, midTile2.col, tile2.row, tile2.col)) {
          return [midTile1, midTile2];
        }
      }
    }

    for (let col = 0; col < this.gridSize; col++) {
      if (this.tiles[row1][col] === null && this.tiles[row1][col] === null) {
        // 检查当前列的 row1 和 row2 位置是否都没有方块
        const midTile1 = { row: row1, col };
        const midTile2 = { row: row2, col };
        if (this.isConnectStraight(tile1.row, tile1.col, midTile1.row, midTile1.col) && this.isConnectStraight(midTile2.row, midTile2.col, tile2.row, tile2.col)) {
          return [midTile1, midTile2];
        }
      }
    }

    return false;
  }
  // 检查是否可以双折角连接
  private isConnectWithTwoTurns(row1: number, col1: number, row2: number, col2: number): any {
    const tile1 = { row: row1, col: col1 }
    const tile2 = { row: row2, col: col2 }
    // 尝试找到折点
    for (let row = 0; row < this.gridSize; row++) {
      if (this.tiles[row][col1] === null && this.tiles[row][col2] === null) {
        const midTile1 = { row, col: col1 };
        const midTile2 = { row, col: col2 };
        if (this.isConnectStraight(tile1.row, tile1.col, midTile1.row, midTile1.col) && this.isConnectStraight(midTile2.row, midTile2.col, tile2.row, tile2.col)) {
          return [midTile1, midTile2];
        }
      }
    }

    // 尝试所有可能的双折点组合
    for (let row = 0; row < this.gridSize; row++) {
      for (let col = 0; col < this.gridSize; col++) {
        if (this.tiles[row][col] === null) {
          const midTile = { row, col };
          if ((this.isConnectWithOneTurn(tile1.row, tile1.col, midTile.row, midTile.col) && this.isConnectWithOneTurn(midTile.row, midTile.col, tile2.row, tile2.col))) {
            return [midTile];
          }
        }
      }
    }

    return false;
  }
  // 创建爆炸效果
  private createExplosionEffect(tile: Phaser.GameObjects.Image) {
    const row = tile.getData('row');
    const col = tile.getData('col');

    // 创建粒子发射器
    const mainEmitter = this.add.particles(tile.x, tile.y, 'particle_texture', {
      speed: { min: 150, max: 400 },
      angle: { min: 0, max: 360 },
      lifespan: 800,
      scale: { start: 0.7, end: 0 },
      alpha: { start: 1, end: 0 },
      quantity: 15,
      blendMode: 'SCREEN',
      tint: [0xff5555, 0xffff55, 0xffaa00],
      rotate: { start: 0, end: 180 },
      gravityY: 100
    });
    mainEmitter.explode(30);
    // 小火花效果
    // var sparkEmitter = this.add.particles(midX, midY, 'spark_texture', {
    //   speed: { min: 200, max: 500 },
    //   angle: { min: 0, max: 360 },
    //   lifespan: 400,
    //   scale: { start: 0.3, end: 0 },
    //   alpha: { start: 0.8, end: 0 },
    //   quantity: 5,
    //   blendMode: 'ADD',
    //   tint: 0xffffff
    // });
    // sparkEmitter.explode(15);

    // 粒子动画完成后移除连线和粒子系统
    this.time.delayedCall(500, () => {
      mainEmitter.destroy();
      // sparkEmitter.destroy();
      tile.destroy();
      this.tiles[row][col] = null;
    });
  }

  private drawLinesWithGlow(first: { x: number, y: number }, second: { x: number, y: number }, ways: { row: number, col: number }[]) {

    const points: { x: number, y: number }[] = [first, second,]
    //绘制点
    points.forEach(point => {
      const circle = this.add.circle(point.x, point.y, 5, 0xffffff);
      circle.setDepth(2)
      this.pointCircles.push(circle);
    });
    console.log(points, ways);

    const startX = (this.gameWidth - this.gridSize * this.tileSize) / 2;
    const startY = (this.gameHeight - this.gridSize * this.tileSize) / 2;

    ways?.forEach(point => {
      const circle = this.add.circle(startX + point.col * this.tileSize, startY + point.row * this.tileSize, 5, 0xff00ff);
      circle.setDepth(2)
      this.pointCircles.push(circle);
    });

    const glowStrength = 5; // 晕光强度
    const glowColor = 0x00ff00; // 晕光颜色
    let currentIndex = 0;

    return new Promise((r) => {
      const tween = this.tweens.add({
        targets: { progress: 0 },
        progress: 1,
        duration: 500, // 动画总时长
        repeat: points.length - 2, // 重复次数为点数减 2（因为每次连接两个点）
        onUpdate: (tween, target) => {
          const progress = target.progress;
          this.lineGraphics?.clear();
          while (progress > (currentIndex + 1) / (points.length - 1)) {
            currentIndex++;
          }

          const startPoint = points[currentIndex];
          const endPoint = points[currentIndex + 1];
          // 绘制晕光
          for (let i = 0; i < glowStrength; i++) {
            const alpha = 0.1 + (0.9 * (i / glowStrength)); // 从弱到强的透明度
            // const lineWidth = 2 + (i * 2); // 从细到粗的线宽
            const lineWidth = 8; // 从细到粗的线宽
            this.lineGraphics?.lineStyle(lineWidth, glowColor, alpha);
            const line = new Phaser.Geom.Line(
              startPoint.x,
              startPoint.y,
              endPoint.x,
              endPoint.y
            );
            this.lineGraphics?.strokeLineShape(line);
          }

          // 绘制主线
          this.lineGraphics?.lineStyle(2, 0x00ff00, 1);
          const mainLine = new Phaser.Geom.Line(
            startPoint.x,
            startPoint.y,
            endPoint.x,
            endPoint.y
          );
          this.lineGraphics?.strokeLineShape(mainLine);
        },
        onRepeat: () => {
        },
        onComplete: () => {
          // 动画完成后的操作
          // this.lineGraphics?.clear();
          // 动画完成后删除标记的圆点
          // this.pointCircles.forEach(circle => {
          //   circle.destroy();
          // });
          // 连线完成后可以添加消除动画等操作
          r(true)
        }
      })
    })
  }
  // 直线连线动画
  // private drawStraightLineAnimation(first: Phaser.GameObjects.Image, second: Phaser.GameObjects.Image, remove: any) {
  //   console.log('lineGraphics', this.lineGraphics);
  //   const x1 = first.x;
  //   const y1 = first.y;
  //   const x2 = second.x;
  //   const y2 = second.y;
  //   this.lineGraphics?.clear();
  //   const line = new Phaser.Geom.Line(x1, y1, x1, y1);
  //   const tween = this.tweens.add({
  //     targets: line,
  //     x2: x2,
  //     y2: y2,
  //     duration: 200,
  //     onUpdate: () => {
  //       this.lineGraphics?.clear();
  //       this.lineGraphics?.lineStyle(8, 0xffffff, 0.8);  // 白色连线，更粗一些
  //       this.lineGraphics?.strokeLineShape(line);

  //       // 添加发光效果
  //       this.lineGraphics?.lineStyle(4, 0x00ff00, 0.6);  // 绿色内层线
  //       this.lineGraphics?.strokeLineShape(line);
  //     },
  //     onComplete: () => {
  //       this.lineGraphics?.clear();
  //       // 连线完成后可以添加消除动画等操作
  //       remove();
  //     }
  //   });
  // }

  update(): void {
    // 游戏循环更新逻辑
  }
} 